package com.gzc.just.play.last.war.common.handler;

import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 每个客户端连接对应一个虚拟线程的消息处理器
 * 采用"一个连接一个线程"的设计，符合虚拟线程轻量级特性
 */
public class VirtualThreadPerClientHandler {
    private static final Logger logger = LoggerFactory.getLogger(VirtualThreadPerClientHandler.class);
    
    // 会话ID到ClientSession的映射
    private final ConcurrentHashMap<Long, ClientSession> clientSessions = new ConcurrentHashMap<>();
    
    // 消息处理器注册表
    private final ConcurrentHashMap<Integer, SimpleMessageHandler> handlers = new ConcurrentHashMap<>();
    
    /**
     * 注册消息处理器
     */
    public void registerHandler(SimpleMessageHandler handler) {
        handlers.put(handler.getMessageId(), handler);
        logger.info("Registered message handler: {} for message ID: {}", 
                   handler.getName(), handler.getMessageId());
    }
    
    /**
     * 为客户端连接创建并启动一个专用的虚拟线程
     * @param sessionId 客户端会话ID
     * @param ctx Netty通道上下文
     */
    public void startClientSession(long sessionId, ChannelHandlerContext ctx) {
        // 如果已存在该会话，先停止它
        stopClientSession(sessionId);
        
        // 创建并启动新的客户端会话
        ClientSession session = new ClientSession(sessionId, ctx, this, handlers);
        session.start();
        
        clientSessions.put(sessionId, session);
        
        logger.info("Started virtual thread for client session: {}", sessionId);
    }
    
    /**
     * 停止客户端连接的虚拟线程
     * @param sessionId 客户端会话ID
     */
    public void stopClientSession(long sessionId) {
        ClientSession session = clientSessions.get(sessionId);
        if (session != null) {
            session.stop();
            clientSessions.remove(sessionId);
            
            logger.info("Stopped virtual thread for client session: {}", sessionId);
        }
    }
    
    /**
     * 向客户端连接的虚拟线程提交消息
     * @param sessionId 客户端会话ID
     * @param messageId 消息ID
     * @param messageBytes 消息字节数组
     * @return 是否成功提交
     */
    public boolean submitMessage(long sessionId, int messageId, byte[] messageBytes) {
        ClientSession session = clientSessions.get(sessionId);
        if (session == null) {
            logger.warn("Client session {} not found, ignoring message: {}", sessionId, messageId);
            return false;
        }
        
        return session.submitMessage(messageId, messageBytes);
    }
    
    /**
     * 停止所有客户端会话
     */
    public void stopAllSessions() {
        // 复制会话ID列表，避免并发修改异常
        var sessionIds = clientSessions.keySet().toArray(new Long[0]);
        
        for (Long sessionId : sessionIds) {
            stopClientSession(sessionId);
        }
        
        logger.info("Stopped all client sessions");
    }
    
    /**
     * 获取当前活跃的客户端会话数量
     */
    public int getActiveSessionCount() {
        return clientSessions.size();
    }
    
    /**
     * 检查指定会话是否活跃
     */
    public boolean isSessionActive(long sessionId) {
        return clientSessions.containsKey(sessionId);
    }
}